package com.meihuayishu.backend.algorithm;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;

public class CommonCalculator {
    
    // 八卦映射
    private static final Map<Integer, String> GUA_MAP = new HashMap<>();
    // 地支映射
    private static final Map<String, Integer> DIZHI_MAP = new HashMap<>();
    // 时辰映射
    private static final Map<Integer, String> SHICHEN_MAP = new HashMap<>();
    // 变卦映射
    private static final Map<String, Map<Integer, String>> CHANGE_GUA_MAP = new HashMap<>();
    
    static {
        // 初始化八卦映射
        GUA_MAP.put(1, "乾");
        GUA_MAP.put(2, "兑");
        GUA_MAP.put(3, "离");
        GUA_MAP.put(4, "震");
        GUA_MAP.put(5, "巽");
        GUA_MAP.put(6, "坎");
        GUA_MAP.put(7, "艮");
        GUA_MAP.put(0, "坤");
        
        // 初始化地支映射
        DIZHI_MAP.put("子", 1);
        DIZHI_MAP.put("丑", 2);
        DIZHI_MAP.put("寅", 3);
        DIZHI_MAP.put("卯", 4);
        DIZHI_MAP.put("辰", 5);
        DIZHI_MAP.put("巳", 6);
        DIZHI_MAP.put("午", 7);
        DIZHI_MAP.put("未", 8);
        DIZHI_MAP.put("申", 9);
        DIZHI_MAP.put("酉", 10);
        DIZHI_MAP.put("戌", 11);
        DIZHI_MAP.put("亥", 12);
        
        // 初始化时辰映射
        for (int i = 1; i <= 2; i++) SHICHEN_MAP.put(i, "丑");
        for (int i = 3; i <= 4; i++) SHICHEN_MAP.put(i, "寅");
        for (int i = 5; i <= 6; i++) SHICHEN_MAP.put(i, "卯");
        for (int i = 7; i <= 8; i++) SHICHEN_MAP.put(i, "辰");
        for (int i = 9; i <= 10; i++) SHICHEN_MAP.put(i, "巳");
        for (int i = 11; i <= 12; i++) SHICHEN_MAP.put(i, "午");
        for (int i = 13; i <= 14; i++) SHICHEN_MAP.put(i, "未");
        for (int i = 15; i <= 16; i++) SHICHEN_MAP.put(i, "申");
        for (int i = 17; i <= 18; i++) SHICHEN_MAP.put(i, "酉");
        for (int i = 19; i <= 20; i++) SHICHEN_MAP.put(i, "戌");
        for (int i = 21; i <= 22; i++) SHICHEN_MAP.put(i, "亥");
        SHICHEN_MAP.put(23, "子");
        SHICHEN_MAP.put(0, "子");
        
        // 初始化变卦映射
        Map<Integer, String> qianMap = new HashMap<>();
        qianMap.put(1, "巽");
        qianMap.put(2, "离");
        qianMap.put(3, "兑");
        CHANGE_GUA_MAP.put("乾", qianMap);
        
        Map<Integer, String> duiMap = new HashMap<>();
        duiMap.put(1, "坎");
        duiMap.put(2, "震");
        duiMap.put(3, "乾");
        CHANGE_GUA_MAP.put("兑", duiMap);
        
        Map<Integer, String> liMap = new HashMap<>();
        liMap.put(1, "艮");
        liMap.put(2, "乾");
        liMap.put(3, "震");
        CHANGE_GUA_MAP.put("离", liMap);
        
        Map<Integer, String> zhenMap = new HashMap<>();
        zhenMap.put(1, "坤");
        zhenMap.put(2, "兑");
        zhenMap.put(3, "离");
        CHANGE_GUA_MAP.put("震", zhenMap);
        
        Map<Integer, String> xunMap = new HashMap<>();
        xunMap.put(1, "乾");
        xunMap.put(2, "艮");
        xunMap.put(3, "坎");
        CHANGE_GUA_MAP.put("巽", xunMap);
        
        Map<Integer, String> kanMap = new HashMap<>();
        kanMap.put(1, "兑");
        kanMap.put(2, "坤");
        kanMap.put(3, "巽");
        CHANGE_GUA_MAP.put("坎", kanMap);
        
        Map<Integer, String> genMap = new HashMap<>();
        genMap.put(1, "离");
        genMap.put(2, "巽");
        genMap.put(3, "坤");
        CHANGE_GUA_MAP.put("艮", genMap);
        
        Map<Integer, String> kunMap = new HashMap<>();
        kunMap.put(1, "震");
        kunMap.put(2, "坎");
        kunMap.put(3, "艮");
        CHANGE_GUA_MAP.put("坤", kunMap);
    }
    
    /**
     * 根据年月日时计算卦象
     * @param year 年
     * @param month 月
     * @param day 日
     * @param hour 时
     * @return 卦象结果
     */
    public static MeihuaResult calculate(int year, int month, int day, int hour) {
        // 这里简化处理，实际应该使用农历转换
        int lunarYear = year % 12;  // 简化处理
        int lunarMonth = month;
        int lunarDay = day;
        int lunarHour = DIZHI_MAP.get(SHICHEN_MAP.get(hour));
        
        // 计算上卦、下卦和动爻
        int guaUpNum = (lunarDay + lunarMonth + lunarYear) % 8;
        int guaDownNum = (lunarDay + lunarMonth + lunarYear + lunarHour) % 8;
        int guaChange = (lunarDay + lunarMonth + lunarYear + lunarHour) % 6;
        
        // 处理0值
        if (guaUpNum == 0) guaUpNum = 8;
        if (guaDownNum == 0) guaDownNum = 8;
        if (guaChange == 0) guaChange = 6;
        
        // 获取卦名
        String guaUp = GUA_MAP.get(guaUpNum);
        String guaDown = GUA_MAP.get(guaDownNum);
        
        // 确定体卦和用卦
        String guaBody, guaUse;
        String guaChangeName;
        
        if (guaChange <= 3) {
            guaChangeName = CHANGE_GUA_MAP.get(guaDown).get(guaChange);
            guaUse = guaDown;
            guaBody = guaUp;
        } else {
            guaChangeName = CHANGE_GUA_MAP.get(guaUp).get(guaChange - 3);
            guaUse = guaUp;
            guaBody = guaDown;
        }
        
        // 计算互卦（简化处理）
        String guaHuUp = "乾";  // 简化处理
        String guaHuDown = "乾";  // 简化处理
        
        return new MeihuaResult(
            guaUp, 
            guaDown, 
            guaBody, 
            guaUse, 
            guaHuUp, 
            guaHuDown, 
            guaChangeName, 
            guaChange
        );
    }
    
    /**
     * 根据时间戳计算卦象（梅花易数算法）
     * @param timestamp 时间戳
     * @return 卦象结果
     */
    public static MeihuaResult calculateByTimestamp(Long timestamp) {
        // 将时间戳转换为LocalDateTime
        LocalDateTime dateTime = LocalDateTime.ofInstant(
            new java.util.Date(timestamp).toInstant(),
            ZoneId.systemDefault()
        );
        
        // 梅花易数时间起卦算法
        int year = dateTime.getYear();
        int month = dateTime.getMonthValue();
        int day = dateTime.getDayOfMonth();
        int hour = dateTime.getHour();
        
        return calculate(year, month, day, hour);
    }
    
    /**
     * 根据两个数字计算卦象（简单数字起卦）
     * @param num1 上卦数字
     * @param num2 下卦数字
     * @return 卦象结果
     */
    public static MeihuaResult calculateByNumbers(int num1, int num2) {
        int guaUpNum = num1 % 8;
        int guaDownNum = num2 % 8;
        
        // 处理0值
        if (guaUpNum == 0) guaUpNum = 8;
        if (guaDownNum == 0) guaDownNum = 8;
        
        // 获取卦名，确保不为null
        String guaUp = GUA_MAP.get(guaUpNum);
        if (guaUp == null) guaUp = "乾";  // 默认值
        
        String guaDown = GUA_MAP.get(guaDownNum);
        if (guaDown == null) guaDown = "坤";  // 默认值
        
        // 简化处理体卦和用卦
        String guaBody = guaDown;
        String guaUse = guaUp;
        
        // 计算互卦（简化处理）
        String guaHuUp = GUA_MAP.get((guaUpNum + guaDownNum) % 8);
        if (guaHuUp == null) guaHuUp = "乾";  // 默认值
        
        String guaHuDown = GUA_MAP.get((guaUpNum + guaDownNum + 1) % 8);
        if (guaHuDown == null) guaHuDown = "坤";  // 默认值
         
        // 计算变卦（简化处理）
        String guaChange = GUA_MAP.get((guaUpNum + guaDownNum) % 8);
        if (guaChange == null) guaChange = "乾";  // 默认值
        
        // 动爻（简化）
        int changeYao = (guaUpNum + guaDownNum) % 6;
        if (changeYao == 0) changeYao = 6;  // 处理0值
        
        return new MeihuaResult(
            guaUp,
            guaDown,
            guaBody,
            guaUse,
            guaHuUp,   // 互卦上卦
            guaHuDown, // 互卦下卦
            guaChange, // 变卦
            changeYao  // 动爻
        );
    }
    
    /**
     * 梅花易数计算结果类
     */
    public static class MeihuaResult {
        private String guaUp;       // 上卦
        private String guaDown;     // 下卦
        private String guaBody;     // 体卦
        private String guaUse;      // 用卦
        private String guaHuUp;     // 互卦上卦
        private String guaHuDown;   // 互卦下卦
        private String guaChange;   // 变卦
        private int changeYao;      // 动爻

        public MeihuaResult() {
        }

        public MeihuaResult(String guaUp, String guaDown, String guaBody, String guaUse,
                           String guaHuUp, String guaHuDown, String guaChange, int changeYao) {
            this.guaUp = guaUp;
            this.guaDown = guaDown;
            this.guaBody = guaBody;
            this.guaUse = guaUse;
            this.guaHuUp = guaHuUp;
            this.guaHuDown = guaHuDown;
            this.guaChange = guaChange;
            this.changeYao = changeYao;
        }

        // Getters and Setters
        public String getGuaUp() {
            return guaUp;
        }

        public void setGuaUp(String guaUp) {
            this.guaUp = guaUp;
        }

        public String getGuaDown() {
            return guaDown;
        }

        public void setGuaDown(String guaDown) {
            this.guaDown = guaDown;
        }

        public String getGuaBody() {
            return guaBody;
        }

        public void setGuaBody(String guaBody) {
            this.guaBody = guaBody;
        }

        public String getGuaUse() {
            return guaUse;
        }

        public void setGuaUse(String guaUse) {
            this.guaUse = guaUse;
        }

        public String getGuaHuUp() {
            return guaHuUp;
        }

        public void setGuaHuUp(String guaHuUp) {
            this.guaHuUp = guaHuUp;
        }

        public String getGuaHuDown() {
            return guaHuDown;
        }

        public void setGuaHuDown(String guaHuDown) {
            this.guaHuDown = guaHuDown;
        }

        public String getGuaChange() {
            return guaChange;
        }

        public void setGuaChange(String guaChange) {
            this.guaChange = guaChange;
        }

        public int getChangeYao() {
            return changeYao;
        }

        public void setChangeYao(int changeYao) {
            this.changeYao = changeYao;
        }

        @Override
        public String toString() {
            return "MeihuaResult{" +
                    "guaUp='" + guaUp + '\'' +
                    ", guaDown='" + guaDown + '\'' +
                    ", guaBody='" + guaBody + '\'' +
                    ", guaUse='" + guaUse + '\'' +
                    ", guaHuUp='" + guaHuUp + '\'' +
                    ", guaHuDown='" + guaHuDown + '\'' +
                    ", guaChange='" + guaChange + '\'' +
                    ", changeYao=" + changeYao +
                    '}';
        }
    }
}